﻿using System;
using System.Linq;
using Common;
using DAL;
using Models;

namespace BLL
{
    public class UserRegistrationService
    {
        private readonly UserService _userService;
        private readonly EncryptionServie _encryptionService;
        private string passwordFormat = "SHA1";

        public UserRegistrationService()
        {
            _userService = new UserService();
            _encryptionService=new EncryptionServie();
        }

        /// <summary>
        /// Validate customer
        /// </summary>
        /// <param name="usernameOrEmail">Username or email</param>
        /// <param name="password">Password</param>
        /// <returns>Result</returns>
        public bool ValidateCustomer(string usernameOrEmail, string password)
        {
            UserInfo user = null;

            user = _userService.GetCustomerByUsername(usernameOrEmail);

            if (user == null || user.Deleted || !user.Active)
                return false;

            //only registered can login
            if (!user.IsRegistered())
                return false;

            string pwd = "";

            pwd = _encryptionService.CreatePasswordHash(password, user.PasswordSalt, passwordFormat);
            

            bool isValid = pwd == user.Password;

           

            return isValid;
        }

        /// <summary>
        /// Register customer
        /// </summary>
        /// <param name="request">Request</param>
        /// <returns>Result</returns>
        public UserRegistrationResult RegisterCustomer(UserRegistrationRequest request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            if (request.Customer == null)
                throw new ArgumentException("Can't load current customer");

            var result = new UserRegistrationResult();

            if (request.Customer.IsRegistered())
            {
                result.AddError("当前用户已经注册");
                return result;
            }
            if (String.IsNullOrEmpty(request.Email))
            {
                result.AddError("邮件不能为空");
                return result;
            }
            if (!CommonHelper.IsValidEmail(request.Email))
            {
                result.AddError("邮件格式不正确");
                return result;
            }
            if (String.IsNullOrEmpty(request.Password))
            {
                result.AddError("密码不能为空");
                return result;
            }

            if (String.IsNullOrEmpty(request.Username))
            {
                result.AddError("用户名不能为空");
                return result;
            }

            //validate unique user
            if (_userService.GetCustomerByEmail(request.Email) != null)
            {
                result.AddError("Email已经被使用");
                return result;
            }

            if (_userService.GetCustomerByUsername(request.Username) != null)
            {
                result.AddError("用户名已经被使用");
                return result;
            }


            //at this point request is valid
            request.Customer.UserName = request.Username;
            request.Customer.Email = request.Email;
            request.Customer.PasswordFormat = PasswordFormat.Hashed;
            request.Customer.Intro = request.Intro;
            request.Customer.UserLogo = request.UserLogo;

            string saltKey = _encryptionService.CreateSaltKey(5);
            request.Customer.PasswordSalt = saltKey;
            request.Customer.Password = _encryptionService.CreatePasswordHash(request.Password, saltKey,
                                                                              this.passwordFormat);

            request.Customer.Active = request.IsApproved;

            request.Customer.UserType = request.IsVip ? UserType.Vip : UserType.Normal;

            //add to 'Registered' role
            var registeredRole = _userService.GetCustomerRoleBySystemName(SystemCustomerRoleNames.Registered);
            if (registeredRole == null)
                throw new Exception("'Registered' role could not be loaded");

            request.Customer.Roles.Add(registeredRole);

            //remove from 'Guests' role
            var guestRole = request.Customer.Roles.FirstOrDefault(cr => cr.RoleName == SystemCustomerRoleNames.Guests);
            if (guestRole != null)
                request.Customer.Roles.Remove(guestRole);


            _userService.UpdateCustomer(request.Customer);
            return result;
        }
    }
}